package com.gzz.orchid.context.application.rbac.impl;

import com.gzz.orchid.common.core.model.ActionCmd;
import com.gzz.orchid.common.core.util.I18nUtil;
import com.gzz.orchid.context.application.rbac.IRoleExecutor;
import com.gzz.orchid.context.application.rbac.command.RoleSaveCmd;
import com.gzz.orchid.context.application.rbac.convert.RoleConverter;
import com.gzz.orchid.context.domain.rbac.IRoleRepository;
import com.gzz.orchid.context.domain.rbac.IRoleService;
import com.gzz.orchid.context.domain.rbac.entity.Permission;
import com.gzz.orchid.context.domain.rbac.entity.RoleDo;
import com.gzz.orchid.context.infrastructure.definition.Action;
import com.gzz.orchid.context.infrastructure.definition.Status;
import com.gzz.orchid.context.infrastructure.persistence.entity.sys.SysPermissionPo;
import com.gzz.orchid.context.infrastructure.persistence.entity.sys.SysRolePo;
import com.gzz.orchid.context.infrastructure.persistence.mapper.sys.SysPermissionMapper;
import com.gzz.orchid.context.infrastructure.persistence.mapper.sys.SysRoleMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author higmd
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class RoleExecutor implements IRoleExecutor {
    private final SysRoleMapper mapper;
    private final IRoleService service;
    private final IRoleRepository repository;
    private final SysPermissionMapper permissionMapper;

    @Override
    public void save(RoleSaveCmd saveCmd) {
        SysRolePo rolePo;
        if (Objects.isNull(saveCmd.getId())) {
            rolePo = new SysRolePo();
            rolePo.setStatus(0);
        } else {
            rolePo = null; //mapper.selectOneById(saveCmd.getId());
        }
        // 检查code的唯一性
        RoleDo roleDo = new RoleDo();
        roleDo.setCode(saveCmd.getCode());
        roleDo.setId(rolePo.getId());
        service.checkCodeUnique(roleDo);
        //
        //        rolePo.setName(saveCmd.getName());
        //        rolePo.setCode(saveCmd.getCode());
        //        rolePo.setDescription(saveCmd.getDescription());
        RoleConverter
                .INSTANCE
                .updatePo(rolePo, saveCmd);

        // 设置权限
        Set<SysPermissionPo> permSet = saveCmd.getAuthorizes().stream()
                .map(item -> Permission.of(item.getLabel(), saveCmd.getCode(), item.getValue()))
                .map(item -> {
                    SysPermissionPo po = new SysPermissionPo();
                    po.setRoleCode(item.getRoleCode());
                    po.setModuleCode(item.getModuleCode());
                    po.setPurview(item.getActions().stream().mapToInt(Action::getValue).sum());
                    return po;
                })
                .collect(Collectors.toSet());

//        mapper.insertOrUpdateSelective(rolePo);
//        permissionMapper.deleteByCondition(QueryCondition.create(SYS_PERMISSION_PO.ROLE_CODE, "=", rolePo.getCode()));
//        permissionMapper.insertBatch(permSet);
    }

    @Override
    public void delete(ActionCmd cmd) {
        List<RoleDo> modules = repository.findListByIds(cmd.getIds());
        // 验证 不符合抛出异常
        modules.forEach(mDo -> {
            if (mDo.getStatus().equals(Status.ENABLED)) {
                throw new IllegalArgumentException(I18nUtil.ofMessage("角色[%s]当前的状态为[ %s]，不能删除"
                        , mDo.getName()
                        , I18nUtil.message(mDo.getStatus().getLabel())));
            }
        });
        //
        //mapper.deleteBatchByIds(Arrays.asList(cmd.getIds()));
    }

    @Override
    public void disable(ActionCmd cmd) {
        List<RoleDo> roles = repository.findListByIds(cmd.getIds());
        // 验证 不符合抛出异常
        roles.forEach(mDo -> {
            if (!mDo.getStatus().equals(Status.ENABLED)) {
                throw new IllegalArgumentException(I18nUtil.ofMessage("角色[%s]当前的状态为[ %s]，不能禁用"
                        , mDo.getName()
                        , I18nUtil.message(mDo.getStatus().getLabel())));
            }
        });
        //
        repository.batchChangeStatus(Status.DISABLED, roles);
    }

    @Override
    public void enable(ActionCmd cmd) {
        List<RoleDo> roles = repository.findListByIds(cmd.getIds());
        // 验证 不符合抛出异常
        roles.forEach(mDo -> {
            if (!mDo.getStatus().equals(Status.DISABLED)) {
                throw new IllegalArgumentException(I18nUtil.ofMessage("角色[%s]当前的状态为[ %s]，不能启用"
                        , mDo.getName()
                        , I18nUtil.message(mDo.getStatus().getLabel())));
            }
        });
        //
        repository.batchChangeStatus(Status.ENABLED, roles);
    }

    @Override
    public void audit(ActionCmd cmd) {
        List<RoleDo> roles = repository.findListByIds(cmd.getIds());
        // 验证 不符合抛出异常
        roles.forEach(mDo -> {
            if (!mDo.getStatus().equals(Status.CREATED)) {
                throw new IllegalArgumentException(I18nUtil.ofMessage("角色[%s]当前的状态为[ %s]，不能审核"
                        , mDo.getName()
                        , I18nUtil.message(mDo.getStatus().getLabel())));
            }
        });
        //
        repository.batchChangeStatus(Status.ENABLED, roles);
    }
}
